package dws_api

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"server/apps/dws/dws_fld"
	"server/apps/dws/dws_tb"
	"server/dbtools/sql_db"
	"server/global"
	"server/model/common/request"
	"server/model/common/response"

	"server/utils"
	"strings"
)

type DwsApiApi struct {
}

var dwsApiService = DwsApiService{}
var dwsTbService = dws_tb.DwsTbService{}
var dwsFldService = dws_fld.DwsFldService{}


func (dwsApiApi *DwsApiApi) CreateDwsApi(c *gin.Context) {
	var apiConfig ApiConfig
	err := c.ShouldBindJSON(&apiConfig)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	createdBy := utils.GetUserID(c)
	apiConfig.DwsApi.CreatedBy = createdBy
	if err := dwsApiService.CreateDwsApi(&apiConfig.DwsApi); err != nil {
		global.Logger.Error("创建dwsApi失败!", zap.Error(err))
		response.FailWithMessage("创建dwsApi失败", c)
		return
	}
	for idx, oneDwsTb := range apiConfig.DwsTbs {
		oneDwsTb.CreatedBy = createdBy
		oneDwsTb.ApiId = apiConfig.DwsApi.ID
		oneDwsTb.Order = idx
		if idx > 0 {
			if oneDwsTb.JoinType == "" || oneDwsTb.JoinOn == "" {
				global.Logger.Error("联表关系缺失,请修改!")
				response.FailWithMessage("联表关系缺失,请修改!", c)
				return
			}
		}
		if err := dwsTbService.CreateDwsTb(&oneDwsTb); err != nil {
			global.Logger.Error("创建dwsTd失败!", zap.Error(err))
			response.FailWithMessage("创建dwsTd失败", c)
			return
		}
	}
	for _, oneDwsFld := range apiConfig.DwsFlds {
		oneDwsFld.CreatedBy = createdBy
		oneDwsFld.ApiId = apiConfig.DwsApi.ID
		if err := dwsFldService.CreateDwsFld(&oneDwsFld); err != nil {
			global.Logger.Error("创建dwsFld失败!", zap.Error(err))
			response.FailWithMessage("创建dwsFld失败", c)
			return
		}
	}
	response.OkWithMessage("创建dwsApi成功", c)
}


func (dwsApiApi *DwsApiApi) DeleteDwsApi(c *gin.Context) {
	var dwsApi DwsApi
	err := c.ShouldBindJSON(&dwsApi)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	deletedBy := utils.GetUserID(c)
	dwsApi.DeletedBy = deletedBy
	if err := dwsApiService.DeleteDwsApi(dwsApi); err != nil {
		global.Logger.Error("删除失败!", zap.Error(err))
		response.FailWithMessage("删除失败", c)
		return
	}
	if err := dwsTbService.DeleteDwsTbByCol("apiId", dwsApi.ID, deletedBy); err != nil {
		global.Logger.Error("删除失败!", zap.Error(err))
		response.FailWithMessage("删除失败", c)
	}
	if err := dwsFldService.DeleteDwsFldByCol("apiId", dwsApi.ID, deletedBy); err != nil {
		global.Logger.Error("删除失败!", zap.Error(err))
		response.FailWithMessage("删除失败", c)
		return
	}

	response.OkWithMessage("删除成功", c)
}


func (dwsApiApi *DwsApiApi) DeleteDwsApiByIds(c *gin.Context) {
	var IDS request.IdsReq
	err := c.ShouldBindJSON(&IDS)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	deletedBy := utils.GetUserID(c)
	if err := dwsApiService.DeleteDwsApiByIds(IDS, deletedBy); err != nil {
		global.Logger.Error("批量删除api失败!", zap.Error(err))
		response.FailWithMessage("批量删除api失败", c)
	}

	for _, id := range IDS.Ids {
		if err := dwsTbService.DeleteDwsTbByCol("apiId", id, deletedBy); err != nil {
			global.Logger.Error("删除tb失败!", zap.Error(err))
			response.FailWithMessage("删除tb失败", c)
			return
		}
		if err := dwsFldService.DeleteDwsFldByCol("apiId", id, deletedBy); err != nil {
			global.Logger.Error("删除fld失败!", zap.Error(err))
			response.FailWithMessage("删除fld失败", c)
			return
		}
	}

	response.OkWithMessage("批量删除api成功", c)
}


func (dwsApiApi *DwsApiApi) UpdateDwsApi(c *gin.Context) {
	var apiConfig ApiConfig
	err := c.ShouldBindJSON(&apiConfig)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}


	createdBy := utils.GetUserID(c)
	deletedBy := createdBy
	apiConfig.DwsApi.UpdatedBy = utils.GetUserID(c)
	if err := dwsApiService.UpdateDwsApi(apiConfig.DwsApi); err != nil {
		global.Logger.Error("更新dwsApi失败!", zap.Error(err))
		response.FailWithMessage("更新dwsApi失败", c)
	}

	if err := dwsTbService.DeleteDwsTbByCol("apiId", apiConfig.DwsApi.ID, deletedBy); err != nil {
		global.Logger.Error("删除失败!", zap.Error(err))
		response.FailWithMessage("删除失败", c)
		return
	}
	if err := dwsFldService.DeleteDwsFldByCol("apiId", apiConfig.DwsApi.ID, deletedBy); err != nil {
		global.Logger.Error("删除失败!", zap.Error(err))
		response.FailWithMessage("删除失败", c)
		return
	}

	for idx, oneDwsTb := range apiConfig.DwsTbs {
		oneDwsTb.CreatedBy = createdBy
		oneDwsTb.ApiId = apiConfig.DwsApi.ID
		oneDwsTb.Order = idx
		oneDwsTb.ID = 0

		if idx > 0 {
			if oneDwsTb.JoinType == "" || oneDwsTb.JoinOn == "" {
				global.Logger.Error("联表关系缺失,请修改!")
				response.FailWithMessage("联表关系缺失,请修改!", c)
				return
			}
		}
		if err := dwsTbService.CreateDwsTb(&oneDwsTb); err != nil {
			global.Logger.Error("创建dwsTd失败!", zap.Error(err))
			response.FailWithMessage("创建dwsTd失败", c)
			return
		}
	}
	for _, oneDwsFld := range apiConfig.DwsFlds {
		oneDwsFld.CreatedBy = createdBy
		oneDwsFld.ApiId = apiConfig.DwsApi.ID
		oneDwsFld.ID = 0
		if err := dwsFldService.CreateDwsFld(&oneDwsFld); err != nil {
			global.Logger.Error("创建dwsFld失败!", zap.Error(err))
			response.FailWithMessage("创建dwsFld失败", c)
			return
		}
	}
	response.OkWithMessage("更新dwsApi成功", c)
}


func (dwsApiApi *DwsApiApi) FindDwsApi(c *gin.Context) {
	var dwsApi DwsApi
	err := c.ShouldBindQuery(&dwsApi)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	if redwsApi, err := dwsApiService.GetDwsApiById(dwsApi.ID); err != nil {
		global.Logger.Error("查询失败!", zap.Error(err))
		response.FailWithMessage("查询失败", c)
	} else {
		response.OkWithData(gin.H{"redwsApi": redwsApi}, c)
	}
}


func (dwsApiApi *DwsApiApi) GetDwsApiList(c *gin.Context) {
	var pageInfo DwsApiSearch
	err := c.ShouldBindQuery(&pageInfo)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	if list, total, err := dwsApiService.GetDwsApiInfoList(pageInfo); err != nil {
		global.Logger.Error("获取失败!", zap.Error(err))
		response.FailWithMessage("获取失败", c)
	} else {
		response.OkWithDetailed(response.PageResult{
			List:     list,
			Total:    total,
			Page:     pageInfo.Page,
			PageSize: pageInfo.PageSize,
		}, "获取成功", c)
	}
}


func (dwsApiApi *DwsApiApi) GetAllDwsApis(c *gin.Context) {
	dwsApi, err := dwsApiService.GetAllDwsApis()
	if err != nil {
		global.Logger.Error("获取失败!", zap.Error(err))
		response.FailWithMessage("获取失败", c)
	} else {
		response.OkWithDetailed(gin.H{"dwsApi": dwsApi}, "获取成功", c)
	}
}


func (dwsApiApi *DwsApiApi) GetDwsApi(c *gin.Context) {
	var apiId uint
	err := c.ShouldBindJSON(&apiId)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	apiConfig, err1 := dwsApiService.GetDwsApi(apiId)
	if err1 != nil {
		global.Logger.Error("获取失败!", zap.Error(err1))
		response.FailWithMessage("获取失败", c)
	} else {
		response.OkWithDetailed(gin.H{"apiConfig": apiConfig}, "获取成功", c)
	}
}


func (dwsApiApi *DwsApiApi) InitDwsApi(c *gin.Context) {
	response.FailWithMessage("获取初始化数据失败", c)
}


func (dwsApiApi *DwsApiApi) GetData(c *gin.Context) {
	var apiRequest ApiRequest
	err := c.ShouldBindJSON(&apiRequest)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	var dwsApi DwsApi
	err = global.SysDB.Where("topicCode = ? and code = ?", apiRequest.Topic, apiRequest.Name).First(&dwsApi).Error

	apiConfig, err1 := dwsApiService.GetDwsApi(dwsApi.ID)
	if err1 != nil {
		global.Logger.Error("获取失败!", zap.Error(err1))
		response.FailWithMessage("获取失败", c)
	}

	if len(apiConfig.DwsFlds) == 0 {
		global.Logger.Error("获取失败!字段选择数为0。", zap.Error(err1))
		response.FailWithMessage("获取失败！字段选择数为0。", c)
		return
	}
	var selectString string
	selectString += "select "
	for idx, oneDwsFld := range apiConfig.DwsFlds {
		oneSelect := fmt.Sprintf("t%d.%s %s", oneDwsFld.SrcTbId, oneDwsFld.SrcFldName, oneDwsFld.DwsFldName)
		selectString += oneSelect
		if idx < len(apiConfig.DwsFlds)-1 {
			selectString += ","
		}
	}
	if len(apiConfig.DwsTbs) == 0 {
		global.Logger.Error("获取失败!数据表选择数为0。", zap.Error(err1))
		response.FailWithMessage("获取失败！数据表选择数为0。", c)
		return
	}
	var fromString string
	fromString += " from "
	for idx, oneDwsTb := range apiConfig.DwsTbs {
		if idx == 0 {
			oneFrom := fmt.Sprintf("%s t%d", oneDwsTb.SrcTbName, oneDwsTb.SrcTbId)
			fromString += oneFrom
		}
		if idx > 0 {
			if oneDwsTb.JoinType == "" || oneDwsTb.JoinOn == "" {
				global.Logger.Error("获取失败!请检查接口配置。", zap.Error(err1))
				response.FailWithMessage("获取失败!请检查接口配置。", c)
				return
			}
			oneFrom := fmt.Sprintf(" %s %s t%d on t%d.%s = t%d.%s",
				oneDwsTb.JoinType,
				oneDwsTb.SrcTbName,
				oneDwsTb.SrcTbId,
				apiConfig.DwsTbs[idx-1].SrcTbId,
				apiConfig.DwsTbs[idx-1].JoinOn,
				oneDwsTb.SrcTbId,
				oneDwsTb.JoinOn,
			)
			fromString += oneFrom
		}
	}
	var whereString string
	if len(apiRequest.ApiFilter) > 0 {
		whereString += " where "
		for idx, oneFilter := range apiRequest.ApiFilter {
			if oneFilter.ColName == "" || oneFilter.Condition == "" || oneFilter.ColValue == "" {
				global.Logger.Error("获取失败!请检查接口配置。", zap.Error(err1))
				response.FailWithMessage("获取失败!请检查接口配置。", c)
				return
			}
			if idx > 0 {
				whereString += " and "
			}
			if strings.IndexFunc(oneFilter.ColName, utils.CheckSpace) >= 0 ||
				strings.IndexFunc(oneFilter.Condition, utils.CheckSpace) >= 0 {
				global.Logger.Error("获取失败!请检查接口请求filter部分,不能有空格。", zap.Error(err1))
				response.FailWithMessage("获取失败!请检查接口请求filter部分,不能有空格。", c)
				return
			}
			count := 0
			for _, oneSrcFld := range apiConfig.DwsFlds {
				if oneSrcFld.DwsFldName == oneFilter.ColName {
					oneWhere := fmt.Sprintf("t%d.%s%s'%s'",
						oneSrcFld.SrcTbId,
						oneSrcFld.SrcFldName,
						oneFilter.Condition,
						oneFilter.ColValue,
					)
					whereString += oneWhere
					count += 1
				}
			}
			if count == 0 {
				global.Logger.Error("获取失败!接口请求filter字段不存在。", zap.Error(err1))
				response.FailWithMessage("获取失败!接口请求filter字段不存在。", c)
				return
			}

			if idx < len(apiRequest.ApiFilter) {
				whereString += " "
			}
		}
	} else {
		whereString = ""
	}
	var sqlString string
	sqlString += selectString
	sqlString += fromString
	sqlString += whereString

	rowResults, err0 := sql_db.QuerySql(global.OdsDB, sqlString)
	if err0 != nil {
		global.Logger.Error("查询数据失败。", zap.Error(err0))
		response.FailWithMessage("查询数据失败。", c)
	}

	response.OkWithData(gin.H{apiRequest.Name: rowResults}, c)
}
